package com.jy.web.diy.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
import com.jy.framework.base.BaseControllerWarpper;
import com.jy.framework.utils.*;
import com.jy.framework.validator.Assert;
import com.jy.web.diy.entity.AttributeEntity;
import com.jy.web.diy.entity.CategoryEntity;
import com.jy.web.diy.entity.JsonEntity;
import com.jy.web.diy.service.AttributeService;
import com.jy.web.diy.service.CategoryService;
import com.jy.web.diy.service.JsonService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jy.web.diy.dao.BaseInfoDao;
import com.jy.web.diy.entity.BaseInfoEntity;
import com.jy.web.diy.service.BaseInfoService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;

@Service("baseInfoService")
public class BaseInfoServiceImpl extends ServiceImpl<BaseInfoDao, BaseInfoEntity> implements BaseInfoService {
    protected Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private AttributeService attributeService;
//    @Autowired
//    private CategoryService categoryService;
    @Autowired
    private JsonService jsonService;
    @Value("${spring.datasource.db-name}")
    private String dbName;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveBaseInfo(BaseInfoEntity entity) {
        entity.setId(R.genUUID());
        this.save(entity);
        List<Map<String, Object>> attributes = entity.getAttributes();
        if (CollectionUtil.isNotEmpty(attributes)) {
            Map<String, Object> jsonValue = attributes.stream().collect(Collectors.toMap(key -> key.get("id") + "", value -> value.get("defaultValue")));
            JsonEntity jsonEntity = new JsonEntity();
            jsonEntity.setJsonValue(FormatterUtils.toFullJsonStr(jsonValue));
            jsonEntity.setId(entity.getId());
            jsonEntity.setCategoryId(entity.getCategoryId());
            jsonService.save(jsonEntity);
        }
    }

    @Override
    public boolean removeById(Serializable id) {
        jsonService.removeById(id);
        return super.removeById(id);
    }

    @Override
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        jsonService.removeByIds(idList);
        return super.removeByIds(idList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBaseInfo(BaseInfoEntity entity) {
        this.updateById(entity);
        List<Map<String, Object>> attributes = entity.getAttributes();
        if (CollectionUtil.isNotEmpty(attributes)) {
            Map<String, Object> jsonValue = attributes.stream().collect(Collectors.toMap(key -> key.get("id") + "", value -> value.getOrDefault("defaultValue","")));
            JsonEntity jsonEntity = new JsonEntity();
            jsonEntity.setJsonValue(FormatterUtils.toFullJsonStr(jsonValue));
            jsonEntity.setId(entity.getId());
            jsonEntity.setCategoryId(entity.getCategoryId());
            jsonService.saveOrUpdate(jsonEntity);
        }
    }

    @Override
    public void saveBatchBaseInfos(List<Map<String, Object>> list, String diyCategoryId, boolean isCode) {
        Set<String> headers = list.get(0).keySet();
        //                                名字转化为对于应字段
        LinkedHashMap<Integer, String> headerMap = new LinkedHashMap<>();
        int index = 0;
        for (Iterator iterator = headers.iterator(); iterator.hasNext(); ) {
            String str = (String) iterator.next();
            headerMap.put(index++, str);
        }
        //名字转化为对于应字段,map结构为index，code； isAttribute为true已经是index，code；
        if (!isCode) {
            handleHeaderToAttributes(headerMap, diyCategoryId);
        } /*else {
            addMissHeaderToAttributes(headerMap, diyCategoryId);
        }*/
//                              此处为了直接入库，需要交换code 为 id,map结构为index，id
        List<Map<String, Object>> attributesMaps = getAttributeMaps(diyCategoryId);
        Map<String, String> codeId = attributesMaps.stream().collect(Collectors.toMap(key -> String.valueOf(key.get("code")), value -> String.valueOf(value.get("id"))));
        for (Map.Entry<Integer, String> v :
                headerMap.entrySet()) {
//            只替换了自定义字段的code，基础表的不变
            if (codeId.keySet().contains(v.getValue())) {
                headerMap.put(v.getKey(), codeId.get(v.getValue()));
            }
        }
//遍历换key
        List<Map<String, Object>> collect = list.stream().map(m -> {
            int i = 0;
            Map<String, Object> da = new HashMap<>(m.size());
            for (Map.Entry<String, Object> m1 : m.entrySet()) {
                String s = headerMap.get(i++);
                da.put(s, m1.getValue());
            }
//           加入 diyCategoryId
            da.put("categoryId",diyCategoryId);
            return da;
        }).collect(Collectors.toList());


//        存数据
        addDiyDataList(collect);
    }

    private void convertList2DiyDatas(List<Map<String, Object>> list, List<BaseInfoEntity> baseInfoEntities, List<JsonEntity> diyJsons) {
        Optional.ofNullable(list).ifPresent(a -> {
            a.forEach(data -> {
                BaseInfoEntity baseInfoEntity = ReflectUtil.newInstance(BaseInfoEntity.class);
                Field[] fields = ReflectUtil.getFieldsDirectly(BaseInfoEntity.class, true);
                Map<String, Object> jsonData = new HashMap<>();
                for (Field field : fields) {
                    field.setAccessible(true);
                    try {
                        String simpleName = field.getType().getSimpleName().toLowerCase();
                        Object value = data.get(field.getName());
                        if (null == value) {
                            continue;
                        }
//                        类型解析

                        // 数值类型
                        List<String> numberTypes = Arrays.asList(double.class.getSimpleName(), float.class.getSimpleName(), int.class.getSimpleName(), Integer.class.getSimpleName().toLowerCase(), BigDecimal.class.getSimpleName().toLowerCase(), long.class.getSimpleName().toLowerCase());
                        if (numberTypes.contains(simpleName)) {
                            long aLong = Long.parseLong(String.valueOf(value));
                            field.set(baseInfoEntity, aLong);
//                            data.remove(field.getName());
                        }

//            字符串类型
                        if (String.class.getSimpleName().equalsIgnoreCase(simpleName)) {
//                            if (StringUtils.isBlank((String) value)) {
//                                continue;
//                            }
                            field.set(baseInfoEntity, value);
//                            data.remove(field.getName());
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
//                获取json字段
                data.forEach((k, v) -> {
                    if (NumberUtil.isNumber(k)) {
                        jsonData.put(k, v);
                    }
                });
                baseInfoEntity.setId(R.genUUID());
                baseInfoEntities.add(baseInfoEntity);

                JsonEntity jsonEntity = new JsonEntity();
                jsonEntity.setId(baseInfoEntity.getId());
                jsonEntity.setCategoryId(baseInfoEntity.getCategoryId());
                jsonEntity.setJsonValue(FormatterUtils.toFullJsonStr(jsonData));
                diyJsons.add(jsonEntity);
            });
        });

    }

    @Override
    public void addDiyDataList(List<Map<String, Object>> list) {
        List<BaseInfoEntity> diyBaseInfos = new ArrayList<>();
        List<JsonEntity> diyJsons = new ArrayList<>();
        convertList2DiyDatas(list, diyBaseInfos, diyJsons);
        this.saveBatch(diyBaseInfos);
        jsonService.saveBatch(diyJsons);
    }

    @Override
    public List<Map<String, Object>> getAttributeMaps(String diyCategoryId) {
        AttributeEntity diyCategory = new AttributeEntity();
        diyCategory.setCategoryId(Long.parseLong(diyCategoryId));
        return this.getAttributeMaps(diyCategory);
    }

    private void handleHeaderToAttributes(LinkedHashMap<Integer, String> indexNameMap, String diyCategoryId) {
        LinkedHashMap<String, String> attrNameCodeMap = generateNameCode(diyCategoryId);
        Set<String> attrNames = attrNameCodeMap.keySet();
        for (Map.Entry<Integer, String> indexName : indexNameMap.entrySet()) {
            if (attrNames.contains(indexName.getValue())) {
                String attrCode = attrNameCodeMap.get(indexName.getValue());
                indexNameMap.put(indexName.getKey(), FormatterUtils.toLowerCamel(attrCode));
//              为了保证所有字段完备性，此处先移除已经加入的字段，一会儿再加进来，为了保证表头index对齐
                attrNames.remove(indexName.getValue());
                continue;
            }
        }
//      补全excel 中缺失的自定义字段，以后存入json中才不会出错
        for (String attrName : attrNames) {
            indexNameMap.put(indexNameMap.size() + 1, attrNameCodeMap.get(attrName));
        }
    }

    private void addMissHeaderToAttributes(LinkedHashMap<Integer, String> indexCodeMap, String diyCategoryId) {
        LinkedHashMap<String, String> attrCodeIdMap = generateCodeId(diyCategoryId);
        Set<String> attrCodes = attrCodeIdMap.keySet();
        for (Map.Entry<Integer, String> indexCode : indexCodeMap.entrySet()) {
            if (attrCodes.contains(indexCode.getValue())) {
                String attrCode = attrCodeIdMap.get(indexCode.getValue());
                indexCodeMap.put(indexCode.getKey(), FormatterUtils.toLowerCamel(attrCode));
//              为了保证所有字段完备性，此处先移除已经加入的字段，一会儿再加进来，为了保证表头index对齐
                attrCodes.remove(indexCode.getValue());
                continue;
            }
        }
//      补全excel 中缺失的自定义字段，以后存入json中才不会出错
        for (String attrCode : attrCodes) {
            indexCodeMap.put(indexCodeMap.size() + 1, attrCode);
        }
    }


    public LinkedHashMap<String, String> generateNameCode(String diyCategoryId) {
        LinkedHashMap<String, String> headerMap = new LinkedHashMap<>();
        Optional<List<Map<String, Object>>> tableInfo = this.getTableInfo(BaseInfoEntity.class);
        tableInfo.ifPresent(to -> {
            Map<String, String> columnHeader = to.stream().collect(Collectors.toMap(key -> FormatterUtils.toLowerCamel(String.valueOf(key.get("columnComment"))), value -> String.valueOf(value.get("columnName"))));
            headerMap.putAll(columnHeader);
            if (StringUtils.isNotBlank(diyCategoryId)) {
                List<Map<String, Object>> attributesMaps = getAttributeMaps(diyCategoryId);
                Map<String, String> attributeHeader = attributesMaps.stream().collect(Collectors.toMap(key -> FormatterUtils.toLowerCamel(String.valueOf(key.get("name"))), value -> String.valueOf(value.get("code"))));
                headerMap.putAll(attributeHeader);
            }
        });
        return headerMap;
    }

    public LinkedHashMap<String, String> generateCodeId(String diyCategoryId) {
        LinkedHashMap<String, String> headerMap = new LinkedHashMap<>();
        Optional<List<Map<String, Object>>> tableInfo = this.getTableInfo(BaseInfoEntity.class);
        tableInfo.ifPresent(to -> {
            Map<String, String> columnHeader = to.stream().collect(Collectors.toMap(key -> FormatterUtils.toLowerCamel(String.valueOf(key.get("columnComment"))), value -> String.valueOf(value.get("columnName"))));
            headerMap.putAll(columnHeader);
            if (StringUtils.isNotBlank(diyCategoryId)) {
                List<Map<String, Object>> attributesMaps = getAttributeMaps(diyCategoryId);
                Map<String, String> attributeHeader = attributesMaps.stream().collect(Collectors.toMap(key -> FormatterUtils.toLowerCamel(String.valueOf(key.get("code"))), value -> String.valueOf(value.get("id"))));
                headerMap.putAll(attributeHeader);
            }
        });
        return headerMap;
    }

    /**
     * @param entity
     * @Author: JuiceYan
     * @Description: 获取表字段信息
     * @param: [tableName]
     * @return: java.util.List<java.util.Map                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               java.lang.Object>>
     * @throws:
     * @Date: 11:10 2018/7/14
     */
    @Override
    public Optional<List<Map<String, Object>>> getTableInfo(Class entity) {
        List<Map<String, Object>> columns = new ArrayList<>();
        Optional.ofNullable(entity).ifPresent(cl -> {
            String tableName = ((TableName) cl.getAnnotation(TableName.class)).value();
            String sql = "select column_name columnName, data_type dataType, column_comment columnComment, column_key columnKey, extra from information_schema.columns where TABLE_NAME='" + tableName + "' and table_schema = (select database()) order by ordinal_position";
            columns.addAll(SqlRunner.db().selectList(sql));
        });
        return Optional.ofNullable(columns);
    }



    @Override
    public List<Map<String, Object>> getAttributeMaps(AttributeEntity entity) {
        LambdaQueryWrapper<AttributeEntity> queryWrapper = new QueryWrapper<AttributeEntity>().lambda().eq(AttributeEntity::getCategoryId, entity.getCategoryId()).orderByAsc(AttributeEntity::getOrderNum);
        return attributeService.listMaps(queryWrapper);
    }

    @Override
    public List<String> getReservedAttributeNames() {
        return this.baseMapper.getReservedAttributeNames();
    }

    @Override
    public IPage<Map<String, Object>> selectValuesMapPage(Page page, Map<String, Object> conditionMap, boolean isCode) {
        IPage<Map<String, Object>> mapIPage = baseMapper.selectValuesMapPage(page, conditionMap);
        if (CollectionUtil.isEmpty(mapIPage.getRecords())) {
            return mapIPage;
        }
        wrapper(mapIPage, isCode);
        return mapIPage;
    }

    @Override
    public List<Map<String, Object>> selectValuesMaps(Map<String, Object> conditionMap) {
        List<Map<String, Object>> mapList = baseMapper.selectValuesMapPage(conditionMap);
        if (CollectionUtil.isEmpty(mapList)) {
            return mapList;
        }
        wrapper(mapList, false);
        return mapList;
    }

    private void wrapper(Object mapList, boolean isCode) {
        Map<String, String> idCode = new HashMap<>();
        if (isCode) {
//        从数据里面获取字段id
            List<String> ids = getAttributeIds(mapList);
            List<AttributeEntity> entities = (List<AttributeEntity>) attributeService.listByIds(ids);
            idCode.putAll(entities.stream().collect(Collectors.toMap(id -> String.valueOf(id.getId()), AttributeEntity::getCode)));
        }
        BaseControllerWarpper.warp(mapList, map -> {
            String jsonValue = (String) map.get("jsonValue");
            JSONObject jsonObject = JSONObject.parseObject(jsonValue);
            if (isCode) {
                idCode.forEach((i, c) -> {
                    jsonObject.put(c, jsonObject.get(i));
                    jsonObject.remove(i);
                });
            }
            map.remove("jsonValue");
            if (jsonObject != null) {
                map.putAll(jsonObject);
            }
        });
    }

    private List<String> getAttributeIds(Object obj) {
        List<String> strings = new ArrayList<>();
        if (null == obj) {
            return strings;
        }
        if (obj instanceof List) {
            List<Map<String, Object>> list = (List<Map<String, Object>>) obj;
            for (Map<String, Object> map : list) {
                return getJsonValueIds(strings, map);
            }
        } else if (obj instanceof IPage) {
            IPage page = (IPage) obj;
            List records = page.getRecords();
            for (Object map : records) {
                if (map instanceof Map) {
                    Map<String, Object> map1 = (Map<String, Object>) map;
                    return getJsonValueIds(strings, map1);
                } else {
                    Map<String, Object> map1 = BeanMap.create(map);
                    return getJsonValueIds(strings, map1);
                }
            }
        }
        return strings;
    }

    private List<String> getJsonValueIds(List<String> strings, Map<String, Object> map) {
        String jsonValue = (String) map.get("jsonValue");
        JSONObject jsonObject = JSONObject.parseObject(jsonValue);
        strings.addAll(jsonObject.keySet());
        return strings;
    }

    @Override
    public PageUtils getCategoryDataList(Map<String, Object> conditions, boolean isCode) {
        Map<String, Object> conditionMap = new HashMap<>(10);
//        用来查询单条数据
        conditionMap.put("id", conditions.get("id"));

        conditionMap.put("attributeId", conditions.get("attributeId"));
        conditionMap.put("remark", "");
        conditionMap.put("value", "");
        if (null != conditions.get("categoryId")) {
            conditionMap.put("categoryId", conditions.get("categoryId"));
        }
        String queryByRemarks = (String) conditions.get("remark");
        String queryByName = (String) conditions.get("name");
        String queryByValue = (String) conditions.get("value");
        String orderColumn = (String) conditions.get("sidx");
        String order = (String) conditions.get("order");

        if (StringUtils.isNotBlank(queryByRemarks)) {
            conditionMap.put("remark", queryByRemarks.replaceAll(" +", ""));
        }
        if (StringUtils.isNotBlank(queryByName)) {
            conditionMap.put("name", queryByName.replaceAll(" +", ""));
        }
        if (StringUtils.isNotBlank(queryByValue)) {
            conditionMap.put("value", queryByValue.replaceAll(" +", ""));
        }
        if (StringUtils.isNotBlank(orderColumn) && StringUtils.isNotBlank(order)) {
            conditionMap.put("orderColumn", orderColumn.replaceAll(" +", ""));
            conditionMap.put("order", order.replaceAll(" +", ""));
        }
        IPage<Map<String, Object>> page = this.selectValuesMapPage(new Query<BaseInfoEntity>(conditions).getPage(), conditionMap, isCode);

        return new PageUtils(page);
    }

    @Override
    public BaseInfoEntity getBaseInfoEntity(String id) {
        BaseInfoEntity entity = this.getById(id);
        JsonEntity jsonEntity = jsonService.getById(id);
        if (null != jsonEntity) {
            JSONObject jsonObject = JSONObject.parseObject(jsonEntity.getJsonValue());
            if (jsonObject.size() > 0) {
                Set<String> attrIds = jsonObject.keySet();
                QueryWrapper<AttributeEntity> q = new QueryWrapper<>();
                q.lambda().in(AttributeEntity::getId, attrIds);
                List<Map<String, Object>> mapList = attributeService.listMaps(q);
                mapList.stream().forEach(stringObjectMap -> {
                    stringObjectMap.put("defaultValue", jsonObject.get(stringObjectMap.get("id")));
                });
                entity.setAttributes(mapList);
            }
        }
        return entity;
    }

    @Override
    public void handleCategoryDatas(List<BaseInfoEntity> baseInfoEntities) {
        List<BaseInfoEntity> sorted = new ArrayList<>();
//        map 映射，方便后面遍历取值
        List<String> dataIds = baseInfoEntities.stream().map(BaseInfoEntity::getId).collect(Collectors.toList());
        List<Long> categoryIds = baseInfoEntities.stream().map(BaseInfoEntity::getCategoryId).collect(Collectors.toList());
//获取所有分类
        QueryWrapper<CategoryEntity> categoryWrapper = new QueryWrapper<>();
        categoryWrapper.lambda().ne(CategoryEntity::getType,0).in(CategoryEntity::getId, categoryIds).orderByAsc(CategoryEntity::getOrderNum);
        CategoryService categoryService = SpringContextUtils.getBean(CategoryService.class);
        List<CategoryEntity> diyCategories = categoryService.list(categoryWrapper);
//获取所有分类数据
        QueryWrapper<JsonEntity> jsonEntityQueryWrapper = new QueryWrapper<>();
        jsonEntityQueryWrapper.lambda().in(JsonEntity::getId, dataIds);
        List<JsonEntity> jsonEntities = jsonService.list(jsonEntityQueryWrapper);
        Map<String, JsonEntity> jsonEntityMaps = jsonEntities.stream().collect(Collectors.toMap(JsonEntity::getId, b -> b));

//获取所有分类字段信息
        QueryWrapper<AttributeEntity> attributeEntityQueryWrapper = new QueryWrapper<>();
        attributeEntityQueryWrapper.lambda().in(AttributeEntity::getCategoryId, categoryIds).orderByAsc(AttributeEntity::getOrderNum);
        List<AttributeEntity> attributeEntityList = attributeService.list(attributeEntityQueryWrapper);
        Map<Long, List<AttributeEntity>> attributeEntityMaps = attributeEntityList.stream().collect(Collectors.groupingBy(AttributeEntity::getCategoryId));

//保留顺讯遍历
        Map<Long, List<BaseInfoEntity>> groupMaps = baseInfoEntities.stream().collect(Collectors.groupingBy(BaseInfoEntity::getCategoryId));
        diyCategories.stream().forEachOrdered(entity -> {
            List<BaseInfoEntity> diyBaseInfos1 = groupMaps.get(entity.getId());
            if (!CollectionUtil.isEmpty(diyBaseInfos1)) {
                diyBaseInfos1.forEach(diyBaseInfo1 -> {
                    JsonEntity jsonEntity = jsonEntityMaps.get(diyBaseInfo1.getId());
                    log.info("jsonEntity",jsonEntity);
                    if (null==jsonEntity){
//                       执行下一次遍历，不用 continue
                        return;
                    }
                    JSONObject jsonObject = JSONObject.parseObject(jsonEntity.getJsonValue());
                    if (jsonObject.size() > 0) {
                        List<AttributeEntity> oldAttrs = attributeEntityMaps.get(diyBaseInfo1.getCategoryId()).stream().map(stringObjectMap -> {
                            stringObjectMap.setDefaultValue(String.valueOf(jsonObject.get(String.valueOf(stringObjectMap.getId()))));
                            return stringObjectMap;
                        }).collect(Collectors.toList());
                        List<AttributeEntity> attrs = deepCloneAttributes(oldAttrs);
                        diyBaseInfo1.setAttributeList(attrs);
                    }
                    diyBaseInfo1.setCategoryName(entity.getName());
                    diyBaseInfo1.setCode(entity.getCode());
                    sorted.add(diyBaseInfo1);
                });
            }
        });

        baseInfoEntities.clear();
        baseInfoEntities.addAll(sorted);
    }

    @Override
    public Map<String, Object> getCategoryDataInfo(@PathVariable String id) {
        //        包装一层，beanMap不能直接put
        Map<String, Object> conditions = new HashMap<>();
        BaseInfoEntity baseInfoEntity = getById(id);
        Assert.isNull(baseInfoEntity,"不存在该数据信息！");
        conditions.put("categoryId", baseInfoEntity.getCategoryId());
        conditions.put("id",id);
        PageUtils diyDataList = getCategoryDataList(conditions, true);
        List<?> list = diyDataList.getList();
        if (CollectionUtil.isEmpty(list)){
            return new HashMap<>();
        }
        Map<String, Object> o = (Map<String, Object>) list.get(0);
        return o;
    }

    @Override
    public void saveOnseBaseInfo(Map<String, Object> categoryData, String diyCategoryId, String uuid) {
        Set<String> headers = categoryData.keySet();
        //                                名字转化为对于应字段
        LinkedHashMap<Integer, String> headerMap = new LinkedHashMap<>();
        int index = 0;
        for (Iterator iterator = headers.iterator(); iterator.hasNext(); ) {
            String str = (String) iterator.next();
            headerMap.put(index++, str);
        }
//                              此处为了直接入库，需要交换code 为 id,map结构为index，id
        List<Map<String, Object>> attributesMaps = getAttributeMaps(diyCategoryId);
        Map<String, String> codeId = attributesMaps.stream().collect(Collectors.toMap(key -> String.valueOf(key.get("code")), value -> String.valueOf(value.get("id"))));
        for (Map.Entry<Integer, String> v :
                headerMap.entrySet()) {
//            只替换了自定义字段的code，基础表的不变
            if (codeId.keySet().contains(v.getValue())) {
                headerMap.put(v.getKey(), codeId.get(v.getValue()));
            }
        }
//遍历换key
        int i = 0;
        Map<String, Object> da = new HashMap<>(categoryData.size());
        for (Map.Entry<String, Object> m1 : categoryData.entrySet()) {
            String s = headerMap.get(i++);
            da.put(s, m1.getValue());
        }

        da.put("categoryId",diyCategoryId);
//        存数据


        addDiyData(da, uuid);
    }

    private void addDiyData(Map<String, Object> da, String uuid) {
        BaseInfoEntity diyBaseInfo = new BaseInfoEntity();
        JsonEntity diyJson = new JsonEntity();
        convert2DiyData(da, diyBaseInfo, diyJson, uuid);
        this.save(diyBaseInfo);
        jsonService.save(diyJson);
    }

    private void convert2DiyData(Map<String, Object> data, BaseInfoEntity baseInfoEntity, JsonEntity jsonEntity, String uuid) {

        Field[] fields = ReflectUtil.getFieldsDirectly(BaseInfoEntity.class, true);
        Map<String, Object> jsonData = new HashMap<>();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                String simpleName = field.getType().getSimpleName().toLowerCase();
                Object value = data.get(field.getName());
                if (null == value) {
                    continue;
                }
//                        类型解析

                // 数值类型
                List<String> numberTypes = Arrays.asList(double.class.getSimpleName(), float.class.getSimpleName(), int.class.getSimpleName(), Integer.class.getSimpleName().toLowerCase(), BigDecimal.class.getSimpleName().toLowerCase(), long.class.getSimpleName().toLowerCase());
                if (numberTypes.contains(simpleName)) {
                    long aLong = Long.parseLong(String.valueOf(value));
                    field.set(baseInfoEntity, aLong);
//                            data.remove(field.getName());
                }

//            字符串类型
                if (String.class.getSimpleName().equalsIgnoreCase(simpleName)) {
//                            if (StringUtils.isBlank((String) value)) {
//                                continue;
//                            }
                    field.set(baseInfoEntity, value);
//                            data.remove(field.getName());
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
//                获取json字段
        data.forEach((k, v) -> {
            if (NumberUtil.isNumber(k)) {
                jsonData.put(k, v);
            }
        });
        baseInfoEntity.setId(uuid);

        jsonEntity.setId(baseInfoEntity.getId());
        jsonEntity.setCategoryId(baseInfoEntity.getCategoryId());
        jsonEntity.setJsonValue(FormatterUtils.toFullJsonStr(jsonData));
    }

    private List<AttributeEntity> deepCloneAttributes(List<AttributeEntity> attributesCache) {
        List<AttributeEntity> attributes = new ArrayList<>();
        try {
//               不能直接addAll
            attributes.addAll((List<AttributeEntity>) Clone.deepClone(attributesCache));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return attributes;
    }


    @Override
    public List<BaseInfoEntity> getQrDatas(String name) {
        List<BaseInfoEntity> diyBaseInfos = new ArrayList<>();
        QueryWrapper<BaseInfoEntity> baseInfoEntityQueryWrapper = new QueryWrapper<>();
        baseInfoEntityQueryWrapper.lambda().eq(BaseInfoEntity::getName, name).isNotNull(BaseInfoEntity::getCategoryId).orderBy(true, true, BaseInfoEntity::getCategoryId, BaseInfoEntity::getOrderNum);
        List<BaseInfoEntity> list = list(baseInfoEntityQueryWrapper);
        handleCategoryDatas(list);
        diyBaseInfos.addAll(list);
        return diyBaseInfos;
    }
}
